#include <iostream>

using namespace std;

int i = 0; // expr的全局下标
bool haveError = false;
string expr;

/**
 * 文法产生式如下
 * E ->  TE'
 * E'->  ATE' | ε
 * T ->  FT'
 * T'->  MFT' | ε
 * F ->  (E) | i
 * A ->  + | -
 * M ->  * | /
 ----------------
 * 状态转换表如下
 * |    |   i   |   (   |  )   |    +    |    -    |    *    |    /    |  $   |
 * |:--:| :---: | :---: | :--: | :-----: | :-----: | :-----: | :-----: | :--: |
 * | E  | E→TE' | E→TE' |      |         |         |         |         |      |
 * | T  | T→FT' | T→FT' |      |         |         |         |         |      |
 * | E' |       |       | E'→ε | E'→ATE' | E'→ATE' |         |         | E'→ε |
 * | A  |       |       |      |   A→+   |   A→-   |         |         |      |
 * | F  |  F→i  | F→(E) |      |         |         |         |         |      |
 * | M  |       |       |      |         |         |   M→*   |   M→/   |      |
 * | T' |       |       | T'→ε |   T'→ε  |   T'→ε   | T'→MFT' | T'→MFT' | T'→ε |
 */

void E(char t);

void T(char t);

void E_(char t);

void T_(char t);

void F(char t);

void A(char t);

void M(char t);

void checkError();

void readLexicalResult();

int main(int argc, char** argv)
{
    if (argc < 2)
    {
        cout << "Too few arguments." << endl;
        return 1;
    }
    string path{ argv[1] };
    string name = path.substr(0, path.length() - 7); // 去掉后缀名

    freopen(path.c_str(), "r", stdin); // 重定向输入
    freopen((name + "_rp.txt").c_str(), "w", stdout); // 重定向输出

    readLexicalResult();
    cout << "The Expression is: " << expr << endl;

    E(expr[i]);

    if (!haveError)
        cout << "...This Expression is CORRECT..." << endl;
    else
        cout << "!!!This Expression is ILLEGAL!!!" << endl;
    fclose(stdout);
    return 0;
}

/**
 * @param path 输入的词法分析的结果的文件路径
 * @note 处理词法分析输出的二元组与关键词序列，得到抽象表达式
 */
void readLexicalResult() // 提取词法分析得到的序列
{
    char c;
    string type, word;
    while (cin >> c)
    {
        if (' ' != c) // 过滤空格
            if (c == '<')
            {
                cin >> type >> word;

                if (type == "ID," || type == "NUM,") // 立即数与标识符均视为标识符
                    expr += 'i';
                else if (type == "OP," || (type == "SEP," && (word == "(>" || word == ")>")))
                    expr += word.substr(0, word.length() - 1); // 去除读到的最后一个 >
                else // 非法词汇均视为@
                    expr += '@';
            }
    }

    fclose(stdin);
    expr += '$'; // 结尾加开始符号
}

void E(char t)
{
    if (t == '(' || t == 'i')
    {
        cout << "E -> TE'" << endl;
        T(expr[i]);
        E_(expr[i]);
    }
    else
    {
        checkError();
        ++i;
        if (expr[i] != '$')
            E(expr[i]);
    }
}

void T(char t)
{
    if (t == 'i' || t == '(')
    {
        cout << "T -> FT'" << endl;
        F(expr[i]);
        T_(expr[i]);
    }
    else
    {
        checkError();
        ++i;
        if (expr[i] != '$')
            T(expr[i]);
    }
}

void E_(char t)
{
    if (t == ')' || t == '$')
    {
        cout << "E'-> ε" << endl;
    }
    else if (t == '+' || t == '-')
    {
        cout << "E'-> ATE'" << endl;
        A(expr[i]);
        T(expr[i]);
        E_(expr[i]);
    }
    else
    {
        checkError();
        ++i;
        if (expr[i] != '$')
            E_(expr[i]);
    }
}

void T_(char t)
{
    if (t == ')' || t == '+' || t == '-' || t == '$')
    {
        cout << "T'-> ε" << endl;
    }
    else if (t == '*' || t == '/')
    {
        cout << "T'-> MFT'" << endl;
        M(expr[i]);
        F(expr[i]);
        T_(expr[i]);
    }
    else
    {
        checkError();
        ++i;
        if (expr[i] != '$')
            T_(expr[i]);
    }
}

void F(char t)
{
    if (t == 'i')
    {
        cout << "F -> i" << endl;
        ++i;
    }
    else if (t == '(')
    {
        cout << "F -> (E)" << endl;
        ++i;
        E(expr[i]);
    }
    else
    {
        checkError();
        ++i;
        if (expr[i] != '$')
            F(expr[i]);
    }
}

void A(char t)
{
    if (t == '+')
    {
        cout << "A -> +" << endl;
        ++i;
    }
    else if (t == '-')
    {
        cout << "A -> -" << endl;
        ++i;
    }
    else
    {
        checkError();
        ++i;
        if (expr[i] != '$')
            A(expr[i]);
    }
}

void M(char t)
{
    if (t == '*')
    {
        cout << "M -> *" << endl;
        ++i;
    }
    else if (t == '/')
    {
        cout << "M -> /" << endl;
        ++i;
    }
    else
    {
        checkError();
        ++i;
        if (expr[i] != '$')
            M(expr[i]);
    }
}

void checkError() //发生错误输出,并将此语句的标志改为false
{
    cout << "Error: Production NOT Match" << endl;
    haveError = true;
}

